#include "DynamicArray.h"

// 打印数组
void printArray(int *arr, int size);

// 测试: 异常测试
void errorTest();

// 测试: 基本测试
void basicTest();

// 测试: newDynamicArray() 创建动态数组
void createTest();

// 测试: 添加元素到动态数组
void insertTest();

// 测试: 自动扩容
void dilatationTest();

// 测试: 删除动态数组中的元素
void removeTest();

// 测试: 更改数组中的元素
void updateTest();

// 测试: 查找元素在动态数组中的位置
void findTest();

int main()
{
    basicTest();
    //errorTest();
    return 0;
}

void basicTest()
{
    myInfoLog("下面将进行简单测试，在这一测试过程中出现任何与预期不符的结果均为程序编写错误！");
    createTest();
    insertTest();
    dilatationTest();
    removeTest();
    updateTest();
    findTest();
}

// 测试: newDynamicArray() 创建动态数组
void createTest()
{
    printf("\n");
    myInfoLog("测试: newDynamicArray() 创建动态数组");
    myInfoLog("预期: da->size == 0");
    DynamicArray* da = newDynamicArray();
    myInfoLog();
    printf(" 实际: da->size == %d\n", da->size);
    assertEquals(0, da->size);
    myInfoLog("newDynamicArray() 创建动态数组 测试通过！");
}

// 测试: 添加元素到动态数组
void insertTest()
{
    printf("\n");
    myInfoLog("测试: 添加元素到动态数组");
    DynamicArray* da = newDynamicArray();
    insert(da, 0, 1); // 1
    assertEquals(1, da->size);
    insert(da, da->size, 2); // 1 2
    insert(da, 0, 0);       // 0 1 2
    insert(da, 1, 2);       // 0 2 1 2
    assertEquals(4, da->size);
    int expected[] = {0, 2, 1, 2};
    myInfoLog("预期: 动态数组的元素为:");
    printArray(expected, ARRAY_LENGTH(expected));
    myInfoLog("实际: 动态数组的元素为:");
    printArray(da->datas, da->size);
    assertArrayEquals(expected, da->datas, da->size);
    destroy(da);
    myInfoLog("添加元素到动态数组 测试通过！");
}

// 测试: 自动扩容
void dilatationTest()
{
    printf("\n");
    myInfoLog("测试: 自动扩容");
    DynamicArray* da = newDynamicArray();
    int expected[1000];
    for (int i = 0; i < 1000; i++)
    {
        expected[i] = 1000 - 1 - i;
        insert(da, 0, i);
    }
    assertArrayEquals(expected, da->datas, da->size);
    destroy(da);
    myInfoLog("自动扩容 测试通过！");
}

// 测试: 删除动态数组中的元素
void removeTest()
{
    printf("\n");
    myInfoLog("测试: 删除动态数组中的元素");
    // 0 2 1 2
    DynamicArray* da = newDynamicArray();
    int expected[] = {0, 2, 1, 2};
    for (int i = 0; i < 4; i++)
    {
        insert(da, da->size, expected[i]);
    }

    int expected1[] = {2, 1, 2};
    myInfoLog("remove(da, 0)");
    remove(da, 0);
    assertEquals(3, da->size);
    myInfoLog("预期: 动态数组的元素为:");
    printArray(expected1, ARRAY_LENGTH(expected1));
    myInfoLog("实际: 动态数组的元素为:");
    printArray(da->datas, da->size);
    assertArrayEquals(expected1, da->datas, da->size);

    printf("\n"); // 2 1 2
    myInfoLog("remove(da, 1)");
    remove(da, 1);
    int expected2[] = {2, 2};
    myInfoLog("预期: 动态数组的元素为:");
    printArray(expected2, ARRAY_LENGTH(expected2));
    myInfoLog("实际: 动态数组的元素为:");
    printArray(da->datas, da->size);
    assertArrayEquals(expected2, da->datas, da->size);

    printf("\n"); // 2 2
    myInfoLog("remove(da, 1)");
    remove(da, 1);
    int expected3[] = {2};
    myInfoLog("预期: 动态数组的元素为:");
    printArray(expected3, ARRAY_LENGTH(expected3));
    myInfoLog("实际: 动态数组的元素为:");
    printArray(da->datas, da->size);
    assertArrayEquals(expected3, da->datas, da->size);

    printf("\n"); // 2
    myInfoLog("remove(da, 0)");
    remove(da, 0);
    myInfoLog("预期: 动态数组的元素为:(空)");
    myInfoLog("实际: 动态数组的元素为:");
    printArray(da->datas, da->size);
    assertEquals(0, da->size);
    destroy(da);
    myInfoLog("删除动态数组中的元素 测试通过！");
}

// 测试: 更改数组中的元素
void updateTest()
{
    printf("\n");
    myInfoLog("测试: 更改数组中的元素");
    DynamicArray* da = newDynamicArray();
    int expected[] = {1, 2, 3, 4, 5};
    for (int i = 0; i < 5; i++)
    {
        insert(da, da->size, -1);
    }

    for (int i = 0; i < 5; i++)
    {
        update(da, i, expected[i]);
    }
    myInfoLog("预期: 动态数组的元素为:\n");
    printArray(expected, ARRAY_LENGTH(expected));
    myInfoLog("实际: 动态数组的元素为:");
    printArray(da->datas, da->size);
    assertArrayEquals(expected, da->datas, da->size);
    destroy(da);
    myInfoLog("更改数组中的元素 测试通过！");
}

// 测试: 查找元素在动态数组中的位置
void findTest()
{
    printf("\n");
    myInfoLog("测试: 查找元素在动态数组中的位置");
    DynamicArray* da = newDynamicArray();
    int expected[] = {0, 2, 1, 2};
    for (int i = 0; i < 4; i++)
    {
        insert(da, da->size, expected[i]);
    }

    for (int i = 0; i < 3; i++)
    {
        myInfoLog();
        printf(" 预期: find(%d) == %d\n", expected[i], i);
        int index = find(da, expected[i]);
        myInfoLog();
        printf(" 实际: find(%d) == %d\n", expected[i], index);
        assertEquals(i, index);
    }
    myInfoLog();
    printf(" 预期: find(%d) < 0\n", 99);
    int index = find(da, 99);
    myInfoLog();
    printf(" 实际: find(%d) == %d\n", 99, index);
    assertTrue(index < 0);
    destroy(da);
    myInfoLog("查找元素在动态数组中的位置 测试通过！");
}

// 测试: 异常测试
void errorTest()
{
    printf("\n");
    myInfoLog("下面将进行异常测试，在这一测试过程中所有测试都将导致程序异常，请注意观察输出信息，确保输出了你预期的错误信息！");
    DynamicArray* da = newDynamicArray();
    myInfoLog("测试: 异常测试");
    myInfoLog("预期: 异常: 数组越界");
    //insert(da, -1, 1);
    //insert(da, 1, 1);
    //remove(da, -1);
    //remove(da, 1);
    //update(da, -1, 1);
    //update(da, 1, 1);

    destroy(da);
}

void printArray(int *arr, int size)
{
    for (int i = 0; i < size; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}